package com.aivin.lib_login.ui;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.IdRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import com.aivin.lib_base.tool.WkLog;

public class RecyclerViewFastScroller extends LinearLayout {
    /**
     * 动画执行时间
     */
    private static final int BUBBLE_ANIMATION_DURATION = 100;
    /**
     * alpha 动画
     */
    private ObjectAnimator currentAnimator = null;
    /**
     * 用来进行微调，可以不要
     */
    private static final int TRACK_SNAP_RANGE = 5;

    /**
     * 指示器(显示文字)
     */
    private TextView bubble;
    /**
     * 拖动条
     */
    private View handle;
    private RecyclerView recyclerView;
    /**
     * 当前控件的高度
     */
    private int height;
    private boolean isInitialized = false;


    // region RecyclerView 滚动监听
    private final RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
            updateBubbleAndHandlePosition(); // onScrolled
        }
    };
    // endregion

    public interface BubbleTextGetter {
        String getTextToShowInBubble(int pos);
    }

    // region 构造函数
    public RecyclerViewFastScroller(final Context context, final AttributeSet attrs, final int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public RecyclerViewFastScroller(final Context context) {
        super(context);
        init(context);
    }

    public RecyclerViewFastScroller(final Context context, final AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    // endregion


    // region 初始化 LinearLayout
    protected void init(Context context) {
        if (isInitialized){
            return;
        }
        isInitialized = true;
        setOrientation(HORIZONTAL);
        setClipChildren(false);
    }
    // endregion



    // region 函数重新
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        height = h;
        updateBubbleAndHandlePosition(); // onSizeChanged
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        final int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                if (event.getX() < handle.getX() - ViewCompat.getPaddingStart(handle)){
                    return false;
                }

                if (currentAnimator != null){
                    currentAnimator.cancel();
                }

                if (bubble != null && bubble.getVisibility() == INVISIBLE){
                    showBubble(); // ACTION_DOWN
                }
                handle.setSelected(true);

            case MotionEvent.ACTION_MOVE:
                final float y = event.getY();
                setBubbleAndHandlePosition(y); // ACTION_MOVE
                setRecyclerViewPosition(y);
                return true;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                handle.setSelected(false);
                hideBubble(); //  ACTION_CANCEL 、ACTION_UP
                return true;
        }
        return super.onTouchEvent(event);
    }



    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (recyclerView != null) {
            recyclerView.removeOnScrollListener(onScrollListener);
            recyclerView = null;
        }
    }
    // endregion


    /**
     * 让 recyclerView 跟随 拖动条滚动
     */
    private void setRecyclerViewPosition(float y) {
        if(recyclerView==null){
            return;
        }

        if(recyclerView.getAdapter()==null){
            return;
        }

        float proportion; // 滑块目前所在高度的比例
        if (handle.getY() == 0){
            proportion = 0f;
        }else if (handle.getY() + handle.getHeight() >= height - TRACK_SNAP_RANGE){
            proportion = 1f;
        }else{
            proportion = y / (float) height;
        }


        final int itemCount = recyclerView.getAdapter().getItemCount();
        final int targetPos = getTheMinOne(  itemCount - 1, (int) (proportion * (float) itemCount));

        Object object =  recyclerView.getLayoutManager();
        if(object instanceof  StaggeredGridLayoutManager){
            ((StaggeredGridLayoutManager) object).scrollToPositionWithOffset(targetPos, 0);
        }else if(object instanceof GridLayoutManager){
            ((GridLayoutManager) object).scrollToPositionWithOffset(targetPos, 0);
        }else if(object instanceof LinearLayoutManager){
            ((LinearLayoutManager) object).scrollToPositionWithOffset(targetPos, 0);
        }


        final String bubbleText = ((BubbleTextGetter) recyclerView.getAdapter()).getTextToShowInBubble(targetPos);
        if (bubble != null) {
            bubble.setText(bubbleText);

            if (TextUtils.isEmpty(bubbleText)) {
                hideBubble(); // TextUtils.isEmpty
            } else if (bubble.getVisibility() == View.INVISIBLE) {
                showBubble(); // ACTION_MOVE
            }
        }
    }


    /**
     * 让 滚动条跟随 recyclerView 滚动
     */
    private void updateBubbleAndHandlePosition() {
        if (bubble == null || handle.isSelected()){
            return;
        }

        final int verticalScrollOffset = recyclerView.computeVerticalScrollOffset();
        final int verticalScrollRange = recyclerView.computeVerticalScrollRange();
        float proportion = (float) verticalScrollOffset / ((float) verticalScrollRange - height);
        setBubbleAndHandlePosition(height * proportion); // updateBubbleAndHandlePosition
    }

    //region 设置指示气泡 和图标 位置
    private void setBubbleAndHandlePosition(float y) {
        if(handle==null){
            return;
        }

        final int handleHeight = handle.getHeight();
        int max = height - handleHeight;
        int value = (int) (y - handleHeight / 2);
        float shouldY = getTheMinOne(max, value);
        handle.setY(shouldY ); // handle

        if(bubble==null){
            return;
        }
        int bubbleHeight = bubble.getHeight();
        bubble.setY(getTheMinOne( height - bubbleHeight - handleHeight / 2, (int) (y - bubbleHeight))); // bubble
    }
    // endregion


    private int getTheMinOne(int max, int value) {
        value= value>=0 ? value : 0 ;
        return Math.min(value, max);
    }

    // region 动画
    private void showBubble() {
        if (bubble == null){
            return;
        }
        bubble.setVisibility(VISIBLE);

        if (currentAnimator != null){
            currentAnimator.cancel();
        }

        currentAnimator = ObjectAnimator.ofFloat(bubble, "alpha", 0f, 1f).setDuration(BUBBLE_ANIMATION_DURATION);
        currentAnimator.start();
    }

    private void hideBubble() {

        WkLog.showLog("进入隐藏 hideBubble ");
        if (bubble == null){
            return;
        }

        if (currentAnimator != null){
            currentAnimator.cancel();
        }

        currentAnimator = ObjectAnimator.ofFloat(bubble, "alpha", 1f, 0f).setDuration(BUBBLE_ANIMATION_DURATION);
        currentAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                bubble.setVisibility(INVISIBLE);
                currentAnimator = null;
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                super.onAnimationCancel(animation);
                bubble.setVisibility(INVISIBLE);
                currentAnimator = null;
            }
        });
        currentAnimator.start();
    }
    // endregion


    // region 对外接口
    public void setRecyclerView(final RecyclerView recyclerView) {
        if(this.recyclerView == recyclerView){
            return;
        }

        if (this.recyclerView != null){
            this.recyclerView.removeOnScrollListener(onScrollListener);
        }
        this.recyclerView = recyclerView;

        if (this.recyclerView == null){
            return;
        }
        recyclerView.addOnScrollListener(onScrollListener);
    }

    public void setViewsToUse(@LayoutRes int layoutResId, @IdRes int bubbleResId, @IdRes int handleResId) {
        final LayoutInflater inflater = LayoutInflater.from( getContext());
        inflater.inflate( layoutResId, this, true);

        bubble = findViewById(bubbleResId);
        if (bubble != null){
            bubble.setVisibility(INVISIBLE);
        }
        handle = findViewById(handleResId);
    }
    // endregion
}
